package comp.movel.ubiqua;

import java.io.IOException;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import comp.movel.ubiqua.bd.RankingDAO;
import comp.movel.ubiqua.bluetooth.BluetoothPassaOuRepassaService;
import comp.movel.ubiqua.bluetooth.Constants;
import comp.movel.ubiqua.model.FimDeJogoException;
import comp.movel.ubiqua.model.Placar;
import comp.movel.ubiqua.model.SerializerClass;
import comp.movel.ubiqua.sms.SMS;
import comp.movel.ubiqua.ws.ConexaoWebService;
import comp.movel.ubiqua.ws.PerguntaWSDL;

public class JogoActivity extends Activity implements OnClickListener {
	private Button op[];
	private TextView pergunta, placarString, tempo;
	public ProgressDialog pd;
	public TextView statusConexao;
	private PerguntaWSDL perguntaCorrente;
	public Placar placar;
	private ArrayList<Integer> generatedNumbers = new ArrayList<Integer>();
	public boolean isJogador1 = true, callFinish = false;
	CountDownTimer temporizador;

	// Member object for bluetooth services/connections
	private BluetoothPassaOuRepassaService btService = null;
	// Name of the connected device
	public String mConnectedDeviceName = null;
	// Local Bluetooth adapter jhfjf
	private BluetoothAdapter mBluetoothAdapter = null;
	// The Handler that gets information back from the BluetoothChatService
	private final BluetoothHandler mHandler = new BluetoothHandler(this);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.jogocontroller);
		op = new Button[6];
		op[0] = (Button) findViewById(R.id.button1);
		op[1] = (Button) findViewById(R.id.button2);
		op[2] = (Button) findViewById(R.id.button3);
		op[3] = (Button) findViewById(R.id.button4);
		op[4] = (Button) findViewById(R.id.passa);
		op[5] = (Button) findViewById(R.id.pedirajuda);
		for (int i = 0; i < 4; i++)
			op[i].setOnClickListener(this);
		statusConexao = (TextView) findViewById(R.id.status);
		pergunta = (TextView) findViewById(R.id.pergunta);
		tempo = (TextView) findViewById(R.id.temporestante);
		placarString = (TextView) findViewById(R.id.placar);
		jogarOuAguardar();
		// Pegando local Bluetooth adapter
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		// instanciando o bluetooth services
		btService = new BluetoothPassaOuRepassaService(this, mHandler);
		hidePlacar(true);
		zerarTempo();
	}

	public void iniciarTemporizador() {
		cancelarTemporizador();
		callFinish = true;
		temporizador = new CountDownTimer(30000, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {
				String msg = getResources().getString(R.string.temporestante)
						+ millisUntilFinished / 1000
						+ getResources().getString(R.string.segundos);
				tempo.setText(msg);
			}

			@Override
			public void onFinish() {
				if (callFinish) {
					zerarTempo();
					if (perguntaCorrente != null) {
						if (perguntaCorrente.correto == 0)
							onClick(op[1]);
						else
							onClick(op[0]);
					}
				}
			}
		};
		temporizador.start();
	}


	private void cancelarTemporizador() {
		callFinish = false;
		if (temporizador != null)
			temporizador.cancel();
		zerarTempo();
	}

	private void zerarTempo() {
		String msg = getResources().getString(R.string.temporestante)
				+ getResources().getString(R.string.tempopadrao)
				+ getResources().getString(R.string.segundos);
		tempo.setText(msg);
	}

	public void rodada() {
		Integer id = -100;

		do {
			id = (int) (Math.random() * Constants.NUM_PERGUNTAS_BANCO);
			Log.d(Constants.TAG, "id gerado = " + id);
		} while (generatedNumbers.contains(id));

		generatedNumbers.add(id);

		Log.w("id", "" + id);
		try {
			perguntaCorrente = ConexaoWebService.getPergunta(id);
			if (placar == null) {
				placar = new Placar(perguntaCorrente.id);
			} else {
				placar.setIdPerguntaCorrente(perguntaCorrente.id);
				placar.setValorPergunta(1);
			}

			// Toast.makeText(this, "Jogadores: "+ mBluetoothAdapter.getName() +
			// mConnectedDeviceName, Toast.LENGTH_LONG).show();
			atualizarTela();

		} catch (IOException e) {
			Log.e("Erro", "Sem Internet");
			Toast.makeText(getApplicationContext(),
					getResources().getString(R.string.erro1),
					Toast.LENGTH_SHORT).show();
			finish();
			return;
		} catch (XmlPullParserException e) {
			Toast.makeText(getApplicationContext(),
					getResources().getString(R.string.erro2),
					Toast.LENGTH_SHORT).show();
			finish();
			return;
		}
	}

	public void receberPlacar() {
		try {
			perguntaCorrente = ConexaoWebService.getPergunta(placar
					.getIdPerguntaCorrente());
			generatedNumbers.add(placar.getIdPerguntaCorrente());
			atualizarTela();
		} catch (IOException e) {
			Log.e("Erro", "Sem Internet");
			Toast.makeText(getApplicationContext(),
					getResources().getString(R.string.erro1),
					Toast.LENGTH_SHORT).show();
			finish();
			return;
		} catch (XmlPullParserException e) {
			Log.e("Erro", "Sem Internet");
			Toast.makeText(getApplicationContext(),
					getResources().getString(R.string.erro1),
					Toast.LENGTH_SHORT).show();
			finish();
			return;
		}
	}

	public void jogarOuAguardar() {
		final CharSequence[] items = {
				getResources().getString(R.string.novojogo),
				getResources().getString(R.string.aguardarJogador),
				getResources().getString(R.string.sair) };
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(getResources().getString(R.string.selecioneopcao));
		builder.setItems(items, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case Constants.INICIAR_JOGO:
					rodada();
					Intent serverIntent = new Intent(getApplicationContext(),
							DeviceListActivity.class);
					startActivityForResult(serverIntent,
							Constants.REQUEST_CONNECT_DEVICE);
					break;
				case Constants.AGUARDAR_JOGADOR:
					isJogador1 = false;
					mostrarProgresso();

					pd.setMessage(getResources().getString(
							R.string.bluetooth_waiting));

					ensureDiscoverable();
					break;

				case Constants.SAIR:
					finish();
					break;
				}
			}
		});
		AlertDialog alert = builder.create();
		alert.setCancelable(false);
		alert.show();
	}

	public void atualizarTela() {
		pergunta.setText(perguntaCorrente.pergunta);
		atualizarPlacar();
		op[0].setText(perguntaCorrente.resposta1);
		op[1].setText(perguntaCorrente.resposta2);
		op[2].setText(perguntaCorrente.resposta3);
		op[3].setText(perguntaCorrente.resposta4);
		if (placar.podePassar()) {
			op[4].setText("Passar");
			op[4].setVisibility(View.VISIBLE);
		} else if (placar.podeRepassar()) {
			op[4].setText("Repassar");
			op[4].setVisibility(View.VISIBLE);
		} else
			op[4].setVisibility(View.GONE);
	}

	public void atualizarPlacar() {
		if (mConnectedDeviceName != null) {
			if (isJogador1) {
				placarString
				.setText("Placar:\n " + mBluetoothAdapter.getName()
						+ " - " + placar.getPlacarJog1() + " x "
						+ placar.getPlacarJog2() + " - "
						+ mConnectedDeviceName);
			} else {
				placarString.setText("Placar:\n " + mConnectedDeviceName
						+ " - " + placar.getPlacarJog1() + " x "
						+ placar.getPlacarJog2() + " - "
						+ mBluetoothAdapter.getName());
			}

		} else {
			placarString.setText("Placar:\n Jog1 - " + placar.getPlacarJog1()
					+ " x " + placar.getPlacarJog2() + " - Jog 2 ");
		}
	}

	public void hidePlacar(boolean mustHide) {
		if (mustHide) {
			placarString.setVisibility(View.INVISIBLE);
		} else {
			placarString.setVisibility(View.VISIBLE);
		}
	}

	public void passarOuRepassar(View v) {
		cancelarTemporizador();
		placar.setValorPergunta(placar.getValorPergunta() + 1);
		if (placar.podePassar())
			placar.passar();
		else if (placar.podeRepassar()) {
			placar.repassar();
		}
		sendMessage(SerializerClass.serializePlacar(placar));
	}

	public void pedirAjuda(View v) {
		cancelarTemporizador();
		String mensagem = "Me ajuda no Passa ou Repassa: "
				+ perguntaCorrente.pergunta + " - Opcoes: "
				+ perguntaCorrente.resposta1 + " - "
				+ perguntaCorrente.resposta2 + " - "
				+ perguntaCorrente.resposta3 + " - "
				+ perguntaCorrente.resposta4;
		Intent i = new Intent(this, SMS.class);
		i.putExtra("Mensagem", mensagem);
		startActivity(i);
	}

	@Override
	public void onClick(View v) {
		cancelarTemporizador();
		for (int i = 0; i < 4; i++) {
			if (v.getId() == op[i].getId()) {
				if (jogadorAcertouResposta(i)) {
					try {
						if (placar.isVezJogador1()) {
							placar.setNomeJogadores(
									mBluetoothAdapter.getName(),
									mConnectedDeviceName);
							placar.pontoJog1();

						} else {
							placar.setNomeJogadores(
									mBluetoothAdapter.getName(),
									mConnectedDeviceName);
							placar.pontoJog2();
						}

						Toast.makeText(getApplicationContext(),
								R.string.correct_answer, Toast.LENGTH_SHORT)
								.show();
					} catch (FimDeJogoException e) {
						String msg = e.getMessage();
						e.atualizarRanking();
						sendMessage(SerializerClass.serializePlacar(placar));
						Toast.makeText(getApplicationContext(), msg,
								Toast.LENGTH_LONG).show();
						//sendMessage(msg);
						atualizarRankingLocal();
						finish();
						return;
					}
				} else {
					Toast.makeText(getApplicationContext(),
							R.string.wrong_answer, Toast.LENGTH_SHORT).show();
					if (placar.isVezJogador1()) {
						placar.setPlacarJog1(0);
					} else {
						placar.setPlacarJog2(0);
					}
				}
			}
		}
		placar.setVezJogador1(!placar.isVezJogador1());
		rodada();
		sendMessage(SerializerClass.serializePlacar(placar));
	}

	public void atualizarRankingLocal() {
		RankingDAO ranking = new RankingDAO(getApplicationContext());
		if (isJogador1) {
			ranking.atualizarRanking(mBluetoothAdapter.getName(), placar.getPlacarJog1());
			ranking.atualizarRanking(mConnectedDeviceName, placar.getPlacarJog2());
		}
		else{
			ranking.atualizarRanking(mBluetoothAdapter.getName(), placar.getPlacarJog2());
			ranking.atualizarRanking(mConnectedDeviceName, placar.getPlacarJog1());
		}
	}

	private boolean jogadorAcertouResposta(int i) {
		return i == perguntaCorrente.correto;
	}

	public void mostrarProgresso() {
		pd = new ProgressDialog(this);
		pd.setTitle(getResources().getString(R.string.aguarde));
		pd.setMessage(getResources().getString(R.string.enviandodados));
		pd.show();
	}


	public void removerProgresso() {
		iniciarTemporizador();
		if (pd != null && pd.isShowing())
			pd.dismiss();
	}           



	@Override
	public void onBackPressed() {
		AlertDialog ad = new AlertDialog.Builder(this).create();
		ad.setTitle(getResources().getString(R.string.sair));
		ad.setMessage(getResources().getString(R.string.certezasair));
		ad.setButton(getResources().getString(R.string.sim),
				new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				finish();
			}
		});
		ad.setButton2(getResources().getString(R.string.nao),
				new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
			}
		});
		ad.show();
	}

	// ------------- BLUETOOTH METHODS -------------

	@Override
	public synchronized void onResume() {
		super.onResume();

		Log.e(Constants.TAG, "+ ON RESUME +");

		// Performing this check in onResume() covers the case in which BT was
		// not enabled during onStart(), so we were paused to enable it...
		// onResume() will be called when ACTION_REQUEST_ENABLE activity
		// returns.
		if (btService != null) {
			// Only if the state is STATE_NONE, do we know that we haven't
			// started already
			if (btService.getState() == BluetoothPassaOuRepassaService.STATE_NONE) {
				// Start the Bluetooth chat services
				// Toast.makeText(this, "Listen Start",
				// Toast.LENGTH_LONG).show();
				btService.start();
			}
		}
	}

	private void sendMessage(String message) {
		mostrarProgresso();
		// Check that we're actually connected before trying anything
		if (btService.getState() != BluetoothPassaOuRepassaService.STATE_CONNECTED) {
			Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
			.show();
			removerProgresso();
			perguntaCorrente = null;
			return;
		}
		// Check that there's actually something to send
		if (message.length() > 0) {
			// Get the message bytes and tell the BluetoothService to write
			byte[] send = message.getBytes();
			btService.write(send);
		}
	}

	// funcao que chama a intent de tornar o dispositivo discoverable
	private void ensureDiscoverable() {
		Log.d(Constants.TAG, "ensure discoverable");
		if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
			Intent discoverableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableIntent.putExtra(
					BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
			startActivityForResult(discoverableIntent,
					Constants.DISCOVERY_REQUEST);
		} else {
			Toast.makeText(this, R.string.jaaguardando, Toast.LENGTH_LONG);
		}
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.d(Constants.TAG, "onActivityResult result" + resultCode);
		Log.d(Constants.TAG, "onActivityResult request" + requestCode);
		switch (requestCode) {
		case Constants.REQUEST_CONNECT_DEVICE:
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {
				// Get the device MAC address
				String address = data.getExtras().getString(
						DeviceListActivity.EXTRA_DEVICE_ADDRESS);
				// Get the BLuetoothDevice object
				BluetoothDevice device = mBluetoothAdapter
						.getRemoteDevice(address);
				// Attempt to connect to the device
				btService.connect(device);
			}
			break;
		case Constants.REQUEST_ENABLE_BT:
			// When the request to enable Bluetooth returns
			if (resultCode == Activity.RESULT_OK) {
				// Bluetooth is now enabled
				Log.d(Constants.TAG, "BT is enabled");
				// setupChat();
			} else {
				// User did not enable Bluetooth or an error occured
				Log.d(Constants.TAG, "BT not enabled");
				Toast.makeText(this, R.string.bt_not_enabled_leaving,
						Toast.LENGTH_SHORT).show();
				finish();
			}
			break;
		case Constants.DISCOVERY_REQUEST:
			if (resultCode > 0) {
				Toast.makeText(this, "Adversario ja pode conectar com voce!",
						Toast.LENGTH_SHORT).show();

				// aguardar loading enquanto jogador nao se conecta
			} else {
				Toast.makeText(
						this,
						"Discoberta do bluetooth deu erro, reinicie a aplicacao",
						Toast.LENGTH_SHORT).show();
				finish();
			}
			break;

		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		perguntaCorrente = null;
		cancelarTemporizador();
		removerProgresso();
	}
}
